home *** CD-ROM | disk | FTP | other *** search
/ Chip 2000 October / CHIP Turkiye Ekim 2000.iso / prog / naps / 04 / setup.exe / Gnucleus / GnucleusDoc.cpp < prev    next >
C/C++ Source or Header  |  2000-07-15  |  18KB  |  687 lines

  1. /********************************************************************************
  2.  
  3.     Gnucleus - A node application for the Gnutella network
  4.     Copyright (C) 2000 John Marshall
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  
  19.     For support, questions, comments, etc...
  20.     E-Mail: 
  21.         swabby@c0re.net
  22.     
  23.     Address:
  24.         21 Cadogan Way
  25.         Nashua, NH, USA 03062
  26.  
  27. ********************************************************************************/
  28.  
  29. // GnucleusDoc.cpp : implementation of the CGnucleusDoc class
  30. //
  31.  
  32. #include "stdafx.h"
  33. #include "GnucleusDoc.h"
  34.  
  35. #include "Gnucleus.h"
  36. #include "ViewSearch.h"
  37. #include "ViewSearchSpy.h"
  38. #include "MainFrm.h"
  39.  
  40. #include "GnuTransfer.h"
  41. #include "GnuHash.h"
  42. #include "GnuControl.h"
  43.  
  44. #include "IPFilter.h"
  45.  
  46. #ifdef _DEBUG
  47. #define new DEBUG_NEW
  48. #undef THIS_FILE
  49. static char THIS_FILE[] = __FILE__;
  50. #endif
  51.  
  52. void CGnucleusDoc::QueueCache::PurgeEarliestHostPort(void)
  53. {
  54.     using namespace std;
  55.     list<set<CString>::iterator>::iterator iter = 
  56.             mHostPortsQueue.begin();
  57.     mHostPorts.erase(*iter);
  58.     mHostPortsQueue.pop_front();
  59. }
  60.  
  61. void CGnucleusDoc::QueueCache::AppendLatestHostPort
  62. (
  63.     const CString& inHostPort
  64. )
  65. {
  66.     using namespace std;
  67.     set<CString>::iterator setIter = 
  68.             mHostPorts.insert(inHostPort).first;
  69.     mHostPortsQueue.push_back(setIter);
  70. }
  71.  
  72.  
  73. /////////////////////////////////////////////////////////////////////////////
  74. // CGnucleusDoc
  75.  
  76. IMPLEMENT_DYNCREATE(CGnucleusDoc, CDocument)
  77.  
  78. BEGIN_MESSAGE_MAP(CGnucleusDoc, CDocument)
  79.     //{{AFX_MSG_MAP(CGnucleusDoc)
  80.         // NOTE - the ClassWizard will add and remove mapping macros here.
  81.         //    DO NOT EDIT what you see in these blocks of generated code!
  82.     //}}AFX_MSG_MAP
  83. END_MESSAGE_MAP()
  84.  
  85. /////////////////////////////////////////////////////////////////////////////
  86. // CGnucleusDoc construction/destruction
  87.  
  88. CGnucleusDoc::CGnucleusDoc()
  89. {
  90.     GnuComm = new CGnuControl(this);
  91.  
  92.     TotalHosts = 0;
  93.     m_EstSpeed = 0;
  94.  
  95.     ActiveUploads = 0;
  96.  
  97.     m_readCount = 0;
  98.     m_writeCount = 0;
  99.  
  100.     m_hLangDLL = NULL;
  101.  
  102.     // Load INI, Host file, and shared directories
  103.     ReadINI();
  104.     ReadHostsFile ();
  105.     LoadShare();
  106. }
  107.  
  108. CGnucleusDoc::~CGnucleusDoc()
  109. {
  110.     delete GnuComm;
  111.  
  112.     WriteINI();
  113.     WriteHostsFile();
  114.  
  115.     CIPFilter::Shutdown ();
  116. }
  117.  
  118. BOOL CGnucleusDoc::OnNewDocument()
  119. {
  120.     if (!CDocument::OnNewDocument())
  121.         return FALSE;
  122.  
  123.     TotalHosts = 0;
  124.     // TODO: add reinitialization code here
  125.     // (SDI documents will reuse this document)
  126.  
  127.     return TRUE;
  128. }    
  129.  
  130. void CGnucleusDoc::UpdateSearchViews(packet_QueryReply *QueryReply)
  131. {
  132.     bool Found = 0;
  133.     CString Title;
  134.     POSITION pos = GetFirstViewPosition();
  135.     
  136.  
  137.     while (pos != NULL)
  138.     {
  139.         CView* pView = GetNextView(pos);
  140.         
  141.         pView->GetParentFrame()->GetWindowText(Title);
  142.  
  143.         if(Title.Find("Searching for \"") != -1)
  144.             if(((CViewSearch *) pView)->myGuid == QueryReply->Header.Guid)
  145.             {
  146.                 ((CViewSearch *) pView)->UpdateResults((byte *) QueryReply);
  147.  
  148.                 return;
  149.             }
  150.     }
  151. }
  152.  
  153. void CGnucleusDoc::ReadHostsFile()
  154. {
  155.     CStdioFile infile;
  156.     CString hostFile = "Gnucleus.net";
  157.  
  158.     if (infile.Open(hostFile, CFile::modeCreate | CFile::modeNoTruncate
  159.         | CFile::modeRead))
  160.     {
  161.         CString HostPort;
  162.         while (infile.ReadString(HostPort))
  163.         {
  164.             int a=-1, b=-1, c=-1, d=-1;
  165.             ::sscanf (HostPort, "%d.%d.%d.%d", &a, &b, &c, &d);
  166.             
  167.             if (a > 0 && b > -1 && c > -1 && d > -1)
  168.             {
  169.                 if (CIPFilter::IsPrivateIP(a, b, c, d, a, b, c, d) == 0 &&
  170.                     CIPFilter::AllowIP (a, b, c, d))
  171.                 {
  172.                     HostPort.Remove('\r');
  173.                     HostPort.Remove('\n');
  174.                     SavedHosts.AddTail(HostPort);
  175.                 }
  176.             }
  177.         }
  178.         infile.Close();
  179.     }
  180. }
  181.  
  182.  
  183. void CGnucleusDoc::WriteHostsFile()
  184. {
  185.     CString HostPort, OldHost;
  186.     CString hostFile = "Gnucleus.net";
  187.     
  188.     using namespace std;
  189.     
  190.     while (mQueueCache.mHostPortsQueue.size())
  191.     {
  192.         list<set<CString>::iterator>::iterator iter =
  193.             mQueueCache.mHostPortsQueue.begin();
  194.         while (SavedHosts.GetCount() >= 500)
  195.         {
  196.             OldHost = SavedHosts.RemoveTail();
  197.             //    TRACE("Removed old host %s from SavedHost\n",OldHost);
  198.         }
  199.         SavedHosts.AddHead(**iter);
  200.         //  TRACE("Adding %s to head of SavedHost\n", (LPCTSTR)(**iter));
  201.         mQueueCache.PurgeEarliestHostPort();
  202.     }
  203.     
  204.     CStdioFile outfile;
  205.     if (outfile.Open( hostFile, CFile::modeCreate | CFile::modeWrite))
  206.     {
  207.         
  208.         while( !SavedHosts.IsEmpty() )
  209.         {
  210.             HostPort = SavedHosts.RemoveHead();
  211.             HostPort += "\r\n";
  212.             outfile.WriteString(HostPort);
  213.         }
  214.         
  215.         outfile.Close();
  216.     }
  217. }
  218.  
  219. void CGnucleusDoc::ReadINI()
  220. {
  221.     char buffer[256];
  222.     CString temp, convert, dir;
  223.     CString iniFile = ".\\Gnucleus.ini";
  224.  
  225.     // Connect Settings
  226.     GetPrivateProfileString("Connect", "Port", "0", buffer, 256, iniFile);
  227.     m_ConstPort = atol(buffer);
  228.     
  229.     if(m_ConstPort)
  230.         GnuComm->localPort = m_ConstPort;
  231.     
  232.     GetPrivateProfileString("Connect", "Speed", "0", buffer, 256, iniFile);
  233.     m_ConnectSpeed = atol(buffer);
  234.     
  235.     GetPrivateProfileString("Connect", "Force IP", "0.0.0.0", buffer, 256, iniFile);
  236.     CString strIP(buffer);
  237.     m_ForceIP = StrtoIP(strIP);
  238.     
  239.     GetPrivateProfileString("Connect", "Monitor Type", "2", buffer, 256, iniFile);
  240.     m_MonitorType = atoi(buffer);
  241.     
  242.     GetPrivateProfileString("Connect", "ConnectNum", "3", buffer, 256, iniFile);
  243.     m_ConnectNum = atoi(buffer);
  244.     
  245.     GetPrivateProfileString("Connect", "Timeout", "4", buffer, 256, iniFile);
  246.     m_TimeoutConnect = atoi(buffer);
  247.     
  248.     GetPrivateProfileString("Connect", "Drop for Incoming", "0", buffer, 256, iniFile);
  249.     m_DropForIncoming = (0 != atoi(buffer));
  250.     
  251.     // Search Filter Settings
  252.     int loop;
  253.     
  254.     for(loop = 0; ; ++loop)
  255.     {
  256.         temp.Format ("Item%ld", loop);
  257.         
  258.         if (GetPrivateProfileString ("Search Filter", temp, "", buffer, 256, iniFile) > 0)
  259.         {
  260.             convert = buffer;
  261.             
  262.             int pos = convert.Find(':');
  263.             
  264.             BlockedSearch Search;
  265.             Search.Name = convert.Mid(pos + 1);
  266.             Search.Permis = convert.GetAt(0);
  267.             
  268.             SearchFilter.push_back(Search);
  269.         }
  270.         else
  271.         {
  272.             break;
  273.         }
  274.     }
  275.     
  276.     if( SearchFilter.empty() )
  277.     {
  278.         BlockedSearch Search;
  279.         Search.Name = "*.*";
  280.         Search.Permis = 'A';
  281.         SearchFilter.push_back(Search);
  282.     }
  283.     
  284.     // Filter Settings
  285.     for (loop = 0; ; ++loop)
  286.     {
  287.         temp.Format ("Item%ld", loop);
  288.         
  289.         if (GetPrivateProfileString ("IP Filter", temp, "", buffer, 256, iniFile) > 0)
  290.         {
  291.             convert = buffer;
  292.             convert.Replace("*", "-1");
  293.             convert.Replace('.', ':');
  294.             
  295.             CIPFilter::AddFilter (convert);
  296.         }
  297.         else
  298.         {
  299.             break;
  300.         }
  301.     }
  302.     
  303.     std::vector<CString> FilterList;
  304.     
  305.     CIPFilter::GetConfigStrings( FilterList );
  306.     
  307.     if( FilterList.empty() )
  308.         CIPFilter::AddFilter("A:-1:-1:-1:-1");
  309.     
  310.     // Search Settings
  311.     GetPrivateProfileString("Search", "Max Replies", "64", buffer, 256, iniFile);
  312.     m_MaxReplies = atoi(buffer);
  313.     
  314.     
  315.     // Download Settings
  316.     
  317.     char * default_dir = new char[MAX_PATH];  // for non default desktop directories
  318.     LPITEMIDLIST lp_itemid_list;
  319.     LPMALLOC lp_sh_malloc;
  320.     SHGetMalloc(&lp_sh_malloc);
  321.     SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOPDIRECTORY, &lp_itemid_list);
  322.     SHGetPathFromIDList(lp_itemid_list, default_dir);
  323.     lp_sh_malloc->Free(lp_itemid_list);    // free ITEMID list
  324.     // lp_sh_malloc->Release(); //?
  325.     GetPrivateProfileString("Download", "DownloadDir", _T(default_dir), buffer, 256, iniFile);
  326.     m_DownloadDir = buffer;
  327.     delete [] default_dir;
  328.     
  329.     GetPrivateProfileString("Download", "Max Downloads", "2", buffer, 256, iniFile);
  330.     m_MaxDownloads = atoi(buffer);
  331.     
  332.     GetPrivateProfileString("Download", "Auto Clear", "1", buffer, 256, iniFile);
  333.     m_AutoClearDL = atoi(buffer) ? true : false;
  334.     
  335.     GetPrivateProfileString("Download", "Timeout", "15", buffer, 256, iniFile);
  336.     m_TimeoutDownload = atoi(buffer);
  337.     
  338.     GetPrivateProfileString("Download", "Resume", "1", buffer, 256, iniFile);
  339.     m_ResumeDL = atoi(buffer) ? true : false;
  340.     
  341.     // Upload Settings
  342.     GetPrivateProfileString("Upload", "Max Uploads", "4", buffer, 256, iniFile);
  343.     m_MaxUploads = atoi(buffer);
  344.     
  345.     GetPrivateProfileString("Upload", "Auto Clear", "1", buffer, 256, iniFile);
  346.     m_AutoClearUL = atoi(buffer) ? true : false;
  347.     
  348.     for (loop = 0; ; ++loop)
  349.     {
  350.         temp.Format ("Dir%ld", loop);
  351.         
  352.         
  353.         if (GetPrivateProfileString ("Share", temp, "", buffer, 256,
  354.             iniFile) > 0)
  355.         {
  356.             dir = buffer;
  357.             
  358.             LockUploadData (true);
  359.             SharedDirList.push_back(dir);
  360.             SharedDirCount.push_back(0);
  361.             SharedDirSize.push_back(0);
  362.             UnlockUploadData (true);
  363.         }
  364.         else
  365.             break;
  366.     }
  367.     
  368.     // Bandwidth Settings
  369.     GetPrivateProfileString("Bandwidth", "Drop for Downloads", "0", buffer, 256, iniFile);
  370.     m_AutoDropDL = atoi(buffer) ? true : false;
  371.     
  372.     GetPrivateProfileString("Bandwidth", "Drop for Uploads", "0", buffer, 256, iniFile);
  373.     m_AutoDropUL = atoi(buffer) ? true : false;
  374.     
  375.     GetPrivateProfileString("Bandwidth", "Total Limit", "0", buffer, 256, iniFile);
  376.     m_LimitTotal = atoi(buffer);
  377.     
  378.     GetPrivateProfileString("Bandwidth", "Upload Limit", "0", buffer, 256, iniFile);
  379.     m_LimitUp = atoi(buffer);
  380.     
  381.     GetPrivateProfileString("Bandwidth", "Visual", "1", buffer, 256, iniFile);
  382.     m_BwVisual = atoi(buffer);
  383.     
  384.     // Language Settings
  385.     GetPrivateProfileString("Language", "DLL_Selected", "Default", buffer, 256, iniFile);
  386.     m_strLangDLLex = buffer;
  387.     
  388. }
  389.  
  390. void CGnucleusDoc::WriteINI()
  391.     CString temp,convert;
  392.     CString iniFile = ".\\Gnucleus.ini";
  393.  
  394.     // Connect Settings
  395.     WritePrivateProfileString("Connect", "Port", DWrdtoStr(m_ConstPort), iniFile);
  396.     
  397.     WritePrivateProfileString("Connect", "Speed", DWrdtoStr(m_ConnectSpeed), iniFile);
  398.     
  399.     WritePrivateProfileString("Connect", "Force IP", IPtoStr(m_ForceIP), iniFile);
  400.     
  401.     WritePrivateProfileString("Connect", "Monitor Type", DWrdtoStr(m_MonitorType), iniFile);
  402.     
  403.     WritePrivateProfileString("Connect", "ConnectNum", DWrdtoStr(m_ConnectNum), iniFile);
  404.     
  405.     WritePrivateProfileString("Connect", "Timeout", DWrdtoStr(m_TimeoutConnect), iniFile);
  406.     
  407.     WritePrivateProfileString("Connect", "Drop for Incoming", DWrdtoStr(m_DropForIncoming), iniFile);
  408.     
  409.     int loop;
  410.     // Search Filter
  411.     WritePrivateProfileString("Search Filter", NULL, NULL, iniFile); // First clear out the IPFilters ini file section
  412.     
  413.     std::vector<BlockedSearch>::iterator itSearch;
  414.     
  415.     for (loop = 0, itSearch = SearchFilter.begin (); itSearch != SearchFilter.end (); loop++, itSearch++)
  416.     {
  417.         temp.Format ("Item%ld", loop);
  418.         
  419.         convert = (*itSearch).
  420.             Name;
  421.         
  422.         convert.Insert(0, ":");
  423.         convert.Insert(0, (*itSearch).Permis);
  424.         
  425.         WritePrivateProfileString ("Search Filter", temp, convert,
  426.             iniFile);
  427.     }
  428.     
  429.     // Filter Settings
  430.     WritePrivateProfileString("Filter", NULL, NULL, iniFile); //First clear out the IPFilters ini file section
  431.     
  432.     std::vector<CString>::iterator it;
  433.     std::vector<CString> strings;
  434.     CIPFilter::GetConfigStrings (strings); // Then get the new config strings to write out to the ini file
  435.     
  436.     for (loop = 0, it = strings.begin (); it != strings.end (); loop++, it++)
  437.     {
  438.         temp.Format ("Item%ld", loop);
  439.         convert =  *it;
  440.         convert.Replace("-1", "*");
  441.         convert.Replace(':', '.');
  442.         convert.SetAt(1, ':');
  443.         
  444.         WritePrivateProfileString ("IP Filter", temp, convert, iniFile);
  445.     }
  446.     
  447.     // Search Settings
  448.     WritePrivateProfileString("Search", "Max Replies", DWrdtoStr(m_MaxReplies), iniFile);
  449.     
  450.     // Download Settings
  451.     WritePrivateProfileString("Download", "DownloadDir", m_DownloadDir, iniFile);
  452.     
  453.     WritePrivateProfileString("Download", "Max Downloads", DWrdtoStr(m_MaxDownloads), iniFile);
  454.     
  455.     WritePrivateProfileString("Download", "Auto Clear", WrdtoStr( (int)m_AutoClearDL), iniFile);
  456.     
  457.     WritePrivateProfileString("Download", "Timeout", DWrdtoStr(m_TimeoutDownload), iniFile);
  458.     
  459.     WritePrivateProfileString("Download", "Resume", WrdtoStr( (int)m_ResumeDL), iniFile);
  460.     
  461.     // Upload Settings
  462.     WritePrivateProfileString("Upload", "Max Uploads", DWrdtoStr(m_MaxUploads), iniFile);
  463.     
  464.     WritePrivateProfileString("Upload", "Auto Clear", WrdtoStr( (int)m_AutoClearUL), iniFile);
  465.     
  466.     // First clear out the IPFilters ini file section
  467.     WritePrivateProfileString("Share", NULL, NULL, iniFile); 
  468.     
  469.     LockUploadData (false);
  470.     for (loop = 0, it = SharedDirList.begin (); it != SharedDirList.end ();
  471.     loop++, it++)
  472.     {
  473.         temp.Format ("Dir%ld", loop);
  474.         
  475.         WritePrivateProfileString ("Share", temp, (*it), iniFile);
  476.     }
  477.     UnlockUploadData (false);
  478.     
  479.     // Bandwidth Settings
  480.     WritePrivateProfileString("Bandwidth", "Drop for Downloads", WrdtoStr( (int)m_AutoDropDL), iniFile);
  481.     
  482.     WritePrivateProfileString("Bandwidth", "Drop for Uploads", WrdtoStr( (int)m_AutoDropUL), iniFile);
  483.     
  484.     WritePrivateProfileString("Bandwidth", "Total Limit", DWrdtoStr(m_LimitTotal), iniFile);
  485.     
  486.     WritePrivateProfileString("Bandwidth", "Upload Limit", DWrdtoStr(m_LimitUp), iniFile);
  487.     
  488.     WritePrivateProfileString("Bandwidth", "Visual", DWrdtoStr(m_BwVisual), iniFile);
  489.     
  490.     // Language Settings
  491.     WritePrivateProfileString("Language", "DLL_Selected", m_strLangDLLex, iniFile);
  492.     
  493.     
  494. }
  495.  
  496. void CGnucleusDoc::LoadShare()
  497. {
  498.     CString Path;
  499.     
  500.     std::vector<CString>::iterator itDir;
  501.     std::vector<DWORD>::iterator   itCount;
  502.     std::vector<DWORD>::iterator   itSize;
  503.  
  504.     LockUploadData (true);
  505.     for (itDir = SharedDirList.begin(), itCount = SharedDirCount.begin(), itSize = SharedDirSize.begin();
  506.          itDir != SharedDirList.end(),  itCount != SharedDirCount.end(), itSize != SharedDirSize.end(); 
  507.          itDir++, itCount++, itSize++)
  508.     {
  509.         Path = (*itDir);
  510.  
  511.         if(Path.Find("Recursive") != -1)
  512.             RecurseShare(Path.Mid(0, Path.Find(',')), 1, (*itCount), (*itSize));
  513.         else
  514.             RecurseShare(Path, 0, (*itCount), (*itSize));
  515.     }
  516.  
  517.     UnlockUploadData (true);
  518. }
  519.  
  520. void CGnucleusDoc::RecurseShare(CString File, bool doRecurse, DWORD &DirCount, DWORD &DirSize)
  521. {
  522.     CFileFind finder;
  523.  
  524.     // build a string with wildcards
  525.     CString strWildcard(File);
  526.     CString file_name;
  527.  
  528.     if(strWildcard.GetAt( strWildcard.GetLength() - 1) != '\\')
  529.         strWildcard += _T("\\*.*");
  530.     else
  531.         strWildcard += _T("*.*");
  532.  
  533.     // start working for files
  534.     BOOL bWorking = finder.FindFile(strWildcard);
  535.  
  536.     while (bWorking)
  537.     {
  538.         bWorking = finder.FindNextFile();
  539.  
  540.         // skip . and .. files
  541.         if (finder.IsDots())
  542.          continue;
  543.  
  544.         // if it's a directory, recursively search it
  545.         if (finder.IsDirectory())
  546.         {
  547.             CString str = finder.GetFilePath();
  548.  
  549.             if(doRecurse)
  550.                 RecurseShare(str, 1, DirCount, DirSize);
  551.         }
  552.         else
  553.         {
  554.             SharedFile addFile;
  555.             addFile.FileDir  = finder.GetFilePath();
  556.             addFile.FileName = addFile.FileDir.Mid( addFile.FileDir.ReverseFind('\\') + 1);
  557.             addFile.FileDir.MakeLower();
  558.  
  559.             SharedFiles.push_back(addFile);
  560.             SharedSizes.push_back(finder.GetLength());
  561.  
  562.             DirCount++;
  563.             DirSize += finder.GetLength();
  564.         }
  565.     }
  566.  
  567.     finder.Close();
  568. }
  569.  
  570. void CGnucleusDoc::AddToQueueCache(const CString& inHostPort)
  571. {
  572.     using namespace std;
  573.  
  574.     if (mQueueCache.mHostPorts.end() == 
  575.             mQueueCache.mHostPorts.find(inHostPort))
  576.     {
  577.         if (500 == mQueueCache.mHostPortsQueue.size())
  578.             mQueueCache.PurgeEarliestHostPort();
  579.         mQueueCache.AppendLatestHostPort(inHostPort);
  580.     }
  581. }
  582.  
  583. void CGnucleusDoc::RemoveEarliestHostPort(CString* outHostPort)
  584. {
  585.     ASSERT(outHostPort);
  586.     outHostPort->Empty();
  587.  
  588.     using namespace std;
  589.     if (!mQueueCache.mHostPortsQueue.empty())
  590.     {
  591.         list<set<CString>::iterator>::iterator iter = 
  592.                 mQueueCache.mHostPortsQueue.begin();
  593.         *outHostPort = **iter;
  594.         mQueueCache.PurgeEarliestHostPort();
  595.     }
  596. }
  597.  
  598. void CGnucleusDoc::LockUploadData (bool writeAccess)
  599. {
  600.     while (m_writeCount)    // Writing blocks everyone
  601.     {
  602.         ::Sleep (20);
  603.     }
  604.  
  605.     if (writeAccess)
  606.     {
  607.         m_writeCount++;
  608.  
  609.         ASSERT (m_writeCount == 1);
  610.  
  611.         while (m_readCount)
  612.         {
  613.             ::Sleep (20);
  614.         }
  615.     }
  616.     else
  617.     {
  618.         m_readCount++;
  619.     }
  620. }
  621.  
  622. void CGnucleusDoc::UnlockUploadData (bool writeAccess)
  623. {
  624.     if (writeAccess)
  625.     {
  626.         m_writeCount--;
  627.  
  628.         ASSERT (m_writeCount == 0);
  629.     }
  630.     else
  631.     {
  632.         m_readCount--;
  633.  
  634.         ASSERT (m_readCount >= 0);
  635.     }
  636. }
  637.  
  638. /////////////////////////////////////////////////////////////////////////////
  639. // CGnucleusDoc serialization
  640.  
  641. void CGnucleusDoc::Serialize(CArchive& ar)
  642. {
  643.     if (ar.IsStoring())
  644.     {
  645.         // TODO: add storing code here
  646.     }
  647.     else
  648.     {
  649.         // TODO: add loading code here
  650.     }
  651. }
  652.  
  653. void CGnucleusDoc::UpdateSpy( CString searchText )
  654. {
  655.     CString Title;
  656.     POSITION pos = GetFirstViewPosition();
  657.  
  658.     while (pos != NULL)
  659.     {
  660.         CView* pView = GetNextView(pos);
  661.         
  662.         pView->GetParentFrame()->GetWindowText(Title);
  663.  
  664.         if(Title.Find("Search Spy") != -1)
  665.         ((CViewSearchSpy *) pView)->AddSearchTerm( searchText );
  666.     }
  667. }
  668.  
  669. /////////////////////////////////////////////////////////////////////////////
  670. // CGnucleusDoc diagnostics
  671.  
  672. #ifdef _DEBUG
  673. void CGnucleusDoc::AssertValid() const
  674. {
  675.     CDocument::AssertValid();
  676. }
  677.  
  678. void CGnucleusDoc::Dump(CDumpContext& dc) const
  679. {
  680.     CDocument::Dump(dc);
  681. }
  682. #endif //_DEBUG
  683.  
  684. /////////////////////////////////////////////////////////////////////////////
  685. // CGnucleusDoc commands
  686.